package com.glodon.paas.monitor.server.exposed.facade.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.glodon.paas.consts.StringConst;
import com.glodon.paas.monitor.server.biz.domain.MonitorApplicationEntity;
import com.glodon.paas.monitor.server.biz.domain.MonitorUserAppEntity;
import com.glodon.paas.monitor.server.biz.domain.MonitorUserEntity;
import com.glodon.paas.monitor.server.biz.service.MonitorApplicationService;
import com.glodon.paas.monitor.server.biz.service.MonitorUserAppService;
import com.glodon.paas.monitor.server.biz.service.MonitorUserService;
import com.glodon.paas.monitor.server.constants.MonitorStatusEnum;
import com.glodon.paas.monitor.server.dto.MonitorApplicationUserDTO;
import com.glodon.paas.monitor.server.dto.MonitorResultMsg;
import com.glodon.paas.monitor.server.exception.MonitorException;
import com.glodon.paas.monitor.server.exception.ThrowableUtil;
import com.glodon.paas.monitor.server.exposed.facade.MonitorAppUserFacadeService;
import com.glodon.paas.util.DateUtil;

@Service("monitorAppUserFacadeService")
public class MonitorAppUserFacadeServiceImpl implements MonitorAppUserFacadeService {

	private static final Logger			logger	= LoggerFactory.getLogger(MonitorAppUserFacadeServiceImpl.class);

	@Autowired
	private MonitorApplicationService	monitorApplicationService;

	@Autowired
	private MonitorUserService			monitorUserService;

	@Autowired
	private MonitorUserAppService		monitorUserAppService;

	public MonitorResultMsg<ArrayList<MonitorApplicationEntity>> queryMonitorApplication(MonitorApplicationEntity entity) {

		MonitorResultMsg<ArrayList<MonitorApplicationEntity>> result = new MonitorResultMsg<ArrayList<MonitorApplicationEntity>>();

		if (null == entity) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("query MonitorApplicationUser entity is null.");
			result.setResultObject(null);
			return result;
		}

		ArrayList<MonitorApplicationEntity> monitorApplicationList = monitorApplicationService
				.queryMonitorApplication(entity);

		result.setSuccess(true);
		result.setResultObject(monitorApplicationList);
		return result;
	}

	public MonitorResultMsg<MonitorApplicationUserDTO> findMonitorApplicationUser(Long appId) {

		MonitorResultMsg<MonitorApplicationUserDTO> result = new MonitorResultMsg<MonitorApplicationUserDTO>();

		if (null == appId) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("findMonitorApplicationUser appId is null.");
			result.setResultObject(null);
			return result;
		}

		MonitorApplicationEntity monitorApplication = monitorApplicationService.selectByPrimaryKey(appId);

		if (null == monitorApplication || StringUtils.isBlank(monitorApplication.getAppName())) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("findMonitorApplicationUser monitorApplication is null.");
			result.setResultObject(null);
			return result;
		}

		List<MonitorUserAppEntity> monitorUserAppList = monitorUserAppService.selectByAppId(appId);

		if (null == monitorUserAppList || monitorUserAppList.isEmpty()) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("findMonitorApplicationUser monitorUserAppList is null,appId=" + appId);
			result.setResultObject(null);
			return result;
		}

		MonitorApplicationUserDTO monitorApplicationUserDTO = new MonitorApplicationUserDTO();
		monitorApplicationUserDTO.setMonitorApplicationEntity(monitorApplication);
		monitorApplicationUserDTO.setMonitorUserAppList(monitorUserAppList);
		for (MonitorUserAppEntity userAppEntity : monitorUserAppList) {
			MonitorUserEntity userEntity = monitorUserService.selectByPrimaryKey(userAppEntity.getUserId());
			if (null != userEntity) {
				monitorApplicationUserDTO.getMonitorUserList().add(userEntity);
			}
		}
		result.setSuccess(true);
		result.setResultObject(monitorApplicationUserDTO);
		return result;
	}

	@Transactional
	public MonitorResultMsg<MonitorApplicationEntity> saveMonitorApplicationUser(
			MonitorApplicationEntity monitorApplication, List<String> userIdList) {

		MonitorResultMsg<MonitorApplicationEntity> result = new MonitorResultMsg<MonitorApplicationEntity>();

		if (null == monitorApplication || StringUtils.isBlank(monitorApplication.getAppName())) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("saveMonitorApplicationUser monitorApplication is null.");
			result.setResultObject(null);
			return result;
		}

		if (null == userIdList || userIdList.isEmpty()) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("saveMonitorApplicationUser userIdList is null.");
			result.setResultObject(null);
			return result;
		}

		String appName = monitorApplication.getAppName();
		MonitorApplicationEntity entity = monitorApplicationService.selectByAppName(appName);
		if (null != entity) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("the appName duplicate." + appName);
			result.setResultObject(null);
			return result;
		}

		if (null == monitorApplication.getCreateTime()) {
			monitorApplication.setCreateTime(new Date());
		}

		try {
			monitorApplicationService.insertSelective(monitorApplication);
		} catch (MonitorException mex) {
			MonitorException mEx = ThrowableUtil.clearStackTrace(mex);
			logger.error("saveMonitorApplicationUser_insertSelective:", mEx);
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.SAVE_ERROR);
			result.setResultMsg("saveMonitorApplicationUser monitorApplication Exception." + mEx);
			result.setResultObject(null);
			return result;
		}

		monitorApplication = monitorApplicationService.selectByAppName(appName);
		if (null == monitorApplication) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("saveMonitorApplicationUser the new monitorApplication's appName is null." + appName);
			result.setResultObject(null);
			return result;
		}

		for (String userId : userIdList) {
			MonitorUserAppEntity monitorUserAppEntity = new MonitorUserAppEntity();
			monitorUserAppEntity = new MonitorUserAppEntity();
			monitorUserAppEntity.setAppId(monitorApplication.getId());
			monitorUserAppEntity.setUserId(Long.valueOf(userId));
			monitorUserAppEntity.setCreateTime(new Date());
			monitorUserAppService.insertSelective(monitorUserAppEntity);
		}
		result.setSuccess(true);
		result.setResultObject(monitorApplication);
		return result;
	}

	public MonitorResultMsg<MonitorApplicationEntity> changeMonitorAppStatus(Long appId, String appStatus) {
		MonitorResultMsg<MonitorApplicationEntity> result = new MonitorResultMsg<MonitorApplicationEntity>();
		if (null == appId || StringUtils.isBlank(appStatus)) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("changeMonitorAppStatus appId is null.");
			result.setResultObject(null);
		}

		MonitorApplicationEntity monitorApplication = monitorApplicationService.selectByPrimaryKey(appId);
		if (null != monitorApplication) {
			monitorApplication.setAppStatus(appStatus);
			monitorApplication.setUpdateTime(new Date());
			if (appStatus.equals(MonitorStatusEnum.OFF.getCode())) {
				Integer interval = DateUtil.minBetweenDate(new Date(), monitorApplication.getEffectiveTime());
				if (null != interval && interval.intValue() > 0) {
					monitorApplication.setEffectiveTime(new Date());
				}
			}
			monitorApplicationService.updateByPrimaryKeySelective(monitorApplication);
			result.setSuccess(true);
			result.setResultObject(monitorApplication);
		}
		return result;
	}

	@Transactional
	public MonitorResultMsg<MonitorApplicationEntity> updateMonitorApplicationUser(
			MonitorApplicationEntity monitorApplication, List<String> userIdList) {

		MonitorResultMsg<MonitorApplicationEntity> result = new MonitorResultMsg<MonitorApplicationEntity>();

		if (null == monitorApplication || StringUtils.isBlank(monitorApplication.getAppName())) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("updateMonitorApplicationUser monitorApplication is null.");
			result.setResultObject(null);
			return result;
		}

		monitorApplication.setUpdateTime(new Date());
		try {
			monitorApplicationService.updateByPrimaryKeySelective(monitorApplication);
		} catch (MonitorException mex) {
			MonitorException mEx = ThrowableUtil.clearStackTrace(mex);
			logger.error("updateMonitorApplicationUser_updateByPrimaryKeySelective:", mEx);
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.SAVE_ERROR);
			result.setResultMsg("updateMonitorApplicationUser monitorApplication Exception." + mex.getMessage());
			result.setResultObject(null);
			return result;
		}

		List<MonitorUserAppEntity> monitorUserAppList = monitorUserAppService.selectByAppId(monitorApplication.getId());
		if (null != monitorUserAppList && !monitorUserAppList.isEmpty()) {
			Map<Long, MonitorUserAppEntity> userMap = new HashMap<Long, MonitorUserAppEntity>();
			for (MonitorUserAppEntity monitorUserAppEntity : monitorUserAppList) {
				Long userId = monitorUserAppEntity.getUserId();
				if (null == userMap.get(userId)) {
					userMap.put(userId, monitorUserAppEntity);
				}
			}
			Map<Long, MonitorUserAppEntity> userMapCopy = new HashMap<Long, MonitorUserAppEntity>(userMap.size());
			userMapCopy.putAll(userMap);
			for (String userId : userIdList) {
				if (null == userMap.get(userId)) {
					MonitorUserAppEntity userAppEntity = new MonitorUserAppEntity();
					userAppEntity.setAppId(monitorApplication.getId());
					userAppEntity.setUserId(Long.valueOf(userId));
					userAppEntity.setCreateTime(new Date());
					monitorUserAppService.insertSelective(userAppEntity);
					userMapCopy.remove(userId);
				}
			}
			if (null != userMapCopy && !userMapCopy.isEmpty()) {
				for (Map.Entry<Long, MonitorUserAppEntity> map : userMapCopy.entrySet()) {
					MonitorUserAppEntity userAppEntity = map.getValue();
					monitorUserAppService.deleteByPrimaryKey(userAppEntity.getId());
				}
			}
		} else {
			for (String userId : userIdList) {
				MonitorUserAppEntity userAppEntity = new MonitorUserAppEntity();
				userAppEntity.setAppId(monitorApplication.getId());
				userAppEntity.setUserId(Long.valueOf(userId));
				userAppEntity.setCreateTime(new Date());
				monitorUserAppService.insertSelective(userAppEntity);
			}
		}
		result.setSuccess(true);
		result.setResultObject(monitorApplication);
		return result;
	}

	@Transactional
	public MonitorResultMsg<Boolean> deleteMonitorApplicationUser(Long appId) {

		MonitorResultMsg<Boolean> result = new MonitorResultMsg<Boolean>();
		if (null == appId) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("deleteMonitorApplicationUser appId is null.");
			result.setResultObject(false);
			return result;
		}

		try {
			monitorApplicationService.deleteByPrimaryKey(appId);
		} catch (MonitorException mex) {
			MonitorException mEx = ThrowableUtil.clearStackTrace(mex);
			logger.error("deleteMonitorApplicationUser_deleteByPrimaryKey:", mEx);
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.SAVE_ERROR);
			result.setResultMsg("deleteByPrimaryKey monitorApplication Exception." + mex.getMessage());
			result.setResultObject(false);
			return result;
		}

		List<MonitorUserAppEntity> monitorUserAppList = monitorUserAppService.selectByAppId(appId);

		if (null == monitorUserAppList || monitorUserAppList.isEmpty()) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("selectByAppId monitorUserAppList is null,appId=" + appId);
			result.setResultObject(false);
			return result;
		}

		for (MonitorUserAppEntity monitorUserAppEntity : monitorUserAppList) {
			monitorUserAppService.deleteByPrimaryKey(monitorUserAppEntity.getId());
		}
		result.setSuccess(true);
		result.setResultObject(true);
		return result;
	}

	public MonitorResultMsg<ArrayList<MonitorUserEntity>> queryMonitorUser(MonitorUserEntity entity) {
		MonitorResultMsg<ArrayList<MonitorUserEntity>> result = new MonitorResultMsg<ArrayList<MonitorUserEntity>>();
		if (null == entity) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("queryMonitorUser entity is null.");
			result.setResultObject(null);
			return result;
		}

		ArrayList<MonitorUserEntity> monitorUserList = monitorUserService.queryMonitorUser(entity);

		result.setSuccess(true);
		result.setResultObject(monitorUserList);
		return result;
	}

	public MonitorResultMsg<MonitorUserEntity> loginByUserNameAndPassword(String userName, String password) {
		MonitorResultMsg<MonitorUserEntity> result = new MonitorResultMsg<MonitorUserEntity>();
		if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("loginByUserNameAndPassword userName or password null.");
			result.setResultObject(null);
			return result;
		}

		MonitorUserEntity monitorUser = monitorUserService.loginByUserNameAndPassword(userName, password);
		if (null == monitorUser) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("the userName or password Incorrect.");
			result.setResultObject(null);
			return result;
		}

		result.setSuccess(true);
		result.setResultObject(monitorUser);
		return result;
	}

	@Override
	public MonitorResultMsg<MonitorUserEntity> saveMonitorUser(MonitorUserEntity entity) {
		MonitorResultMsg<MonitorUserEntity> result = new MonitorResultMsg<MonitorUserEntity>();
		if (null == entity) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("saveMonitorUser entity is null.");
			result.setResultObject(null);
			return result;
		}

		if (null == entity.getCreateTime()) {
			entity.setCreateTime(new Date());
		}

		if (StringUtils.isNotBlank(entity.getUserEmail())) {
			if (!entity.getUserEmail().contains(StringConst.GRANDSOFT_EMAIL)) {
				result.setSuccess(false);
				result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
				result.setResultMsg("the grandsoft email is invalid.");
				result.setResultObject(null);
				return result;
			}
		}

		if (StringUtils.isBlank(entity.getUserName())) {
			String emailSplit[] = entity.getUserEmail().split("@");
			entity.setUserName(emailSplit[0]);
			MonitorUserEntity userEntity = monitorUserService.selectByUserName(entity.getUserName());
			if (null != userEntity && StringUtils.isNotBlank(userEntity.getUserName())) {
				result.setSuccess(false);
				result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
				result.setResultMsg("the user name " + entity.getUserName() + " duplicate");
				result.setResultObject(null);
				return result;
			}
		}
		monitorUserService.insertSelective(entity);
		entity = monitorUserService.selectByUserName(entity.getUserName());
		result.setSuccess(true);
		result.setResultObject(entity);
		return result;
	}

	@Override
	public MonitorResultMsg<MonitorUserEntity> updateMonitorUser(MonitorUserEntity entity) {
		MonitorResultMsg<MonitorUserEntity> result = new MonitorResultMsg<MonitorUserEntity>();
		if (null == entity) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("updateMonitorUser entity is null.");
			result.setResultObject(null);
			return result;
		}

		if (null == entity.getUpdateTime()) {
			entity.setUpdateTime(new Date());
		}

		if (StringUtils.isNotBlank(entity.getUserEmail())) {
			if (!entity.getUserEmail().contains(StringConst.GRANDSOFT_EMAIL)) {
				result.setSuccess(false);
				result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
				result.setResultMsg("the grandsoft email is invalid.");
				result.setResultObject(null);
				return result;
			}
		}

		if (StringUtils.isBlank(entity.getUserName())) {
			String emailSplit[] = entity.getUserEmail().split("@");
			entity.setUserName(emailSplit[0]);
		}

		monitorUserService.updateByPrimaryKeySelective(entity);

		entity = monitorUserService.selectByUserName(entity.getUserName());
		result.setSuccess(true);
		result.setResultObject(entity);
		return result;
	}

	@Override
	public MonitorResultMsg<Boolean> deleteMonitorUser(Long userId) {
		MonitorResultMsg<Boolean> result = new MonitorResultMsg<Boolean>();
		if (null == userId) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("deleteMonitorUser userId is null.");
			result.setResultObject(false);
			return result;
		}

		try {
			monitorUserService.deleteByPrimaryKey(userId);
		} catch (MonitorException mex) {
			MonitorException mEx = ThrowableUtil.clearStackTrace(mex);
			logger.error("deleteMonitorUser_deleteByPrimaryKey:", mEx);
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.SAVE_ERROR);
			result.setResultMsg("deleteByPrimaryKey deleteMonitorUser Exception." + mex.getMessage());
			result.setResultObject(false);
			return result;
		}
		result.setSuccess(true);
		result.setResultObject(true);
		return result;
	}

	@Override
	public MonitorResultMsg<MonitorUserEntity> findMonitorUser(Long id) {
		MonitorResultMsg<MonitorUserEntity> result = new MonitorResultMsg<MonitorUserEntity>();

		if (null == id) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("findMonitorUser id is null.");
			result.setResultObject(null);
			return result;
		}

		MonitorUserEntity monitorUserEntity = monitorUserService.selectByPrimaryKey(id);

		if (null == monitorUserEntity || StringUtils.isBlank(monitorUserEntity.getUserName())) {
			result.setSuccess(false);
			result.setResultCode(MonitorException.ErrorCode.PARAM_INVALID);
			result.setResultMsg("findMonitorUser monitorUserEntity is null.");
			result.setResultObject(null);
			return result;
		}

		result.setSuccess(true);
		result.setResultObject(monitorUserEntity);
		return result;
	}
}
